import EventEmitter from "../eventemitter/EventEmitter"
import Gashapon from "../gashapon/Gashapon.js"

const Emit_Change = 'Emit_Change'

export enum GashaponEmit {
    Add = 'Add',
    Remove = 'Remove',
    RemoveAll = 'RemoveAll',
    putBack = 'putBack',
    Reset = 'Reset',
}

export default class GashaponWatcher extends EventEmitter {

    private _Gashapon: Gashapon

    constructor(data: { [name: string]: number }, mode: (0 | 1) = 0, reload = false) {
        super()
        this._Gashapon = new Gashapon({
            mode: mode,
            items: data,
            reload: reload,
        })
    }

    getOrigin() {
        return this._Gashapon.getItems()
    }

    // 牌库方法
    getItemSize() {
        const origin = this.getOrigin();
        return Object.keys(origin).map(v => origin[v]).reduce((pre, curr) => {
            return pre + curr
        }, 0)
    }

    getItemCount(key: string) {
        return this._Gashapon.getItemCount(key);
    }

    getRemain() {
        return this._Gashapon.getRemain();
    }

    getRemainKey() {
        return Object.keys(this.getRemain());
    }

    getRemainSize() {
        const remain = this.getRemain();
        return Object.keys(remain).map(v => remain[v]).reduce((pre, curr) => {
            return pre + curr
        }, 0)
    }

    getRemainCount(key: string) {
        return this._Gashapon.getRemainCount(key);
    }

    add(name: string, count: number = 1, emit = true) {
        this._Gashapon.addItem(name, count);
        if (emit) {
            this.emit(Emit_Change, this, GashaponEmit.Add, name, count);
        }
        return this;
    }

    putBack(name: string, count: number = 1, emit = true) {
        this._Gashapon.putItemBack(name, count);
        if (emit) {
            this.emit(Emit_Change, this, GashaponEmit.putBack, name, count);
        }
        return this;
    }

    next(name?: string, emit = true) {
        const result = this._Gashapon.next(name);
        if (result && emit) {
            this.emit(Emit_Change, this, GashaponEmit.Remove, result, 1);
        }
        return result;
    }

    clear(emit = true) {
        this._Gashapon.removeAllRemain();
        if (emit) {
            this.emit(Emit_Change, this, GashaponEmit.RemoveAll,);
        }
        return this;
    }

    reset(emit = true) {
        this._Gashapon.reset();
        if (emit) {
            this.emit(Emit_Change, this, GashaponEmit.Reset,);
        }
        return this;
    }

    forEachRemain(callback: Gashapon.ForEachItemCallbackType, scope?: object,) {
        this._Gashapon.forEachRemain(callback, scope);
        return this;
    }

    forEachItem(callback: Gashapon.ForEachItemCallbackType, scope?: object,) {
        this._Gashapon.forEachItem(callback, scope)
        return this;
    }

    listenerChange(call: (watcher: GashaponWatcher, type: GashaponEmit) => void) {
        this.on(Emit_Change, call, this)
        return () => {
            this.off(Emit_Change, call, this);
        };
    }
}